<?php

namespace app\api\logic;

use app\common\logic\BaseLogic;
use app\common\model\reimbursement\ExpenseApplication;
use app\common\model\reimbursement\ExpenseOperationLog;
use app\common\model\user\User;
use think\facade\Db;
use think\facade\Log;


class UserExpenseApplicationLogic extends BaseLogic
{
    /**
     * 记录操作日志
     * @param int $expenseId 报账ID
     * @param int $userId 用户ID
     * @param string $content 操作内容
     * @param int $operationType 操作类型
     */
    private static function recordOperation($expenseId, $userId, $content, $operationType)
    {
        $user = User::find($userId);
        $log = new ExpenseOperationLog();
        $log->save([
            'expense_id' => $expenseId,
            'operator_id' => $userId,
            'operator_name' => $user->nickname,
            'operation_type' => $operationType,
            'operation_content' => $content
        ]);
    }

    public static function apply(array $params, int $userId):array
    {
        Db::startTrans();
        try {
            // 获取用户信息
            $user = User::find($userId);
            if (!$user || $user->is_locked) {
                throw new \Exception('账户状态异常，无法提交申请');
            }
            // 获取费用类型
            $expenseType = \app\common\model\reimbursement\ExpenseType::where('id', $params['expense_type_id'])->find();
            if (!$expenseType) {
                throw new \Exception('费用类型不存在');
            }
            // 自动审批逻辑
            $autoApprovalAmount = 5000.00;
            $status = ($params['amount'] < $autoApprovalAmount) ? 3 : 1;
            // 创建申请记录
            $application = new ExpenseApplication();
            $result = $application->save([
                'applicant_id' => $userId,
                'expense_type_id' => $params['expense_type_id'],
                'amount' => $params['amount'],
                'description' => isset($params['description']) ? $params['description'] : '',
                'current_status' => $status,
            ]);
            if ($result){
                // 记录操作日志
                self::recordOperation(
                    $application->id,
                    $userId,
                    "创建报账申请：{$expenseType->name}，金额：{$params['amount']}",
                    1
                );
                Db::commit();
                $data = $application->toArray();
                unset($data['update_time'], $data['id']);
                return [
                    'success' => true,
                    'data' => $data
                ];
            } else {
                throw new \Exception('保存失败');
            }
        } catch (\Exception $e) {
            Db::rollback();
            self::setError($e->getMessage());
            return [
                'success' => false,
                'message' => $e->getMessage(),
            ];
        }
    }

    public static function modify(array $params, int $userId): array
    {
        Db::startTrans();
        try{
            $user = User::find($userId);
            $application = ExpenseApplication::where([
                'id' => $params['id'],
                'applicant_id' => $userId
            ])->findOrEmpty();
            if ($application->isEmpty()){
                throw new \Exception('只能编辑本人发起的申请');
            }
            // 更新数据（仅修改传递的字段）
            $updateData = [];
            $changes = [];
            // 费用类型
            if (isset($params['expense_type_id']) && $params['expense_type_id'] != $application->expense_type_id) {
                $expenseType = \app\common\model\reimbursement\ExpenseType::where('id', $params['expense_type_id'])->find();
                if (!$expenseType) {
                    throw new \Exception('费用类型不存在');
                }
                $oldType = \app\common\model\reimbursement\ExpenseType::where('id', $application->expense_type_id)->value('name');
                $updateData['expense_type_id'] = $params['expense_type_id'];
                $changes['expense_type'] = [
                    'old' => $oldType,
                    'new' => $expenseType->name
                ];
            }
            // 金额
            $autoApprovalAmount = 5000.00;
            $amountChanged = false;
            if (isset($params['amount']) && $params['amount'] != $application->amount) {
                $updateData['amount'] = $params['amount'];
                $changes['amount'] = [
                    'old' => $application->amount,
                    'new' => $params['amount']
                ];
                $amountChanged = true;
            }
            // 描述
            if (isset($params['description']) && $params['description'] !== $application->description) {
                $updateData['description'] = $params['description'];
                $changes['description'] = [
                    'old' => $application->description,
                    'new' => $params['description']
                ];
            }
            // 如果金额被修改，根据新金额更新状态
            if ($amountChanged) {
                $newAmount = $params['amount'];
                if ($newAmount >= $autoApprovalAmount && $application->current_status == 3) {
                    $updateData['current_status'] = 1; // 改为待审核
                    $changes['status'] = [
                        'old' => '已通过',
                        'new' => '待审核'
                    ];
                } else if ($newAmount < $autoApprovalAmount && $application->current_status == 1) {
                    $updateData['current_status'] = 3; // 改为已通过
                    $changes['status'] = [
                        'old' => '待审核',
                        'new' => '已通过'
                    ];
                }
            }
            if (!empty($updateData)) {
                $application->save($updateData);
                // 记录操作日志
                if (!empty($changes)) {
                    $changeDesc = [];
                    foreach ($changes as $field => $change) {
                        if ($field === 'status') {
                            $changeDesc[] = "状态" . $change['old'] . "改为" . $change['new'];
                        } else {
                            $changeDesc[] = $field . "由" . $change['old'] . "改为" . $change['new'];
                        }
                    }
                    self::recordOperation(
                        $application->id,
                        $userId,
                        "修改报账申请：" . implode("，", $changeDesc),
                        2
                    );
                }
            }
            Db::commit();
            $data = $application->toArray();
            unset($data['id'], $data['update_time']);
            return [
                'success' => true,
                'data' => $data
            ];
        } catch (\Exception $e){
            Db::rollback();
            self::setError($e->getMessage());
            return [
                'success' => false,
                'message' => $e->getMessage(),
            ];
        }
    }

    /**
     * 获取报账记录详情
     */
    public static function detail(int $id, int $userId): array
    {
        try {
            $user = User::find($userId);
            if (!$user || $user->is_locked) {
                throw new \Exception('账号状态异常，无法查看详情');
            }
            $application = ExpenseApplication::where([
                'id' => $id,
                'applicant_id' => $userId
            ])->findOrEmpty();
            if ($application->isEmpty()){
                throw new \Exception('申请记录不存在或无权查看');
            }
            $data = $application->toArray();
            unset($data['id'], $data['update_time']);
            // 获取操作日志
            $logs = ExpenseOperationLog::where('expense_id', $id)
                ->order('create_time', 'desc')
                ->select()
                ->toArray();
            $data['operation_logs'] = $logs;
            // 返回申请人id
            $data['applicant_id'] = $application->applicant_id;
            return [
                'success' => true,
                'data' => $data
            ];
        } catch (\Exception $e){
            return [
                'success' => false,
                'message' => $e->getMessage(),
            ];
        }
    }

    public static function lists(int $userId, array $params = []): array
    {
        try {
            $user = User::find($userId);
            if (!$user || $user->is_locked) {
                throw new \Exception('账号状态异常，无法查看详情');
            }
            $where = [];
            // 申请人筛选（支持id）
            if (!empty($params['applicant_id'])) {
                $where[] = ['applicant_id', '=', $params['applicant_id']];
            } else {
                $where[] = ['applicant_id', '=', $userId];
            }
            // 状态筛选
            if (isset($params['status']) && $params['status'] !== '') {
                $where[] = ['current_status', '=', $params['status']];
            }
            // 金额范围筛选
            if (!empty($params['min_amount'])) {
                $where[] = ['amount', '>=', $params['min_amount']];
            }
            if (!empty($params['max_amount'])) {
                $where[] = ['amount', '<=', $params['max_amount']];
            }
            // 时间范围筛选
            if (!empty($params['start_time'])) {
                $where[] = ['create_time', '>=', $params['start_time']];
            }
            if (!empty($params['end_time'])) {
                $where[] = ['create_time', '<=', $params['end_time']];
            }
            // 费用类型筛选
            if (!empty($params['expense_type_id'])) {
                $where[] = ['expense_type_id', '=', $params['expense_type_id']];
            }
            $list = ExpenseApplication::with(['applicant', 'expenseType'])
                ->where($where)
                ->field([
                    'id',
                    'applicant_id',
                    'expense_type_id',
                    'amount',
                    'description',
                    'current_status',
                    'create_time',
                    'update_time'
                ])
                ->order('id', 'desc')
                ->paginate([
                    'page' => $params['page_no'] ?? 1,
                    'list_rows' => $params['page_size'] ?? 15
                ])
                ->toArray();

            $items = $list['data'];
            foreach ($items as &$item) {
                $item['is_self'] = $item['applicant_id'] == $userId;
                $lastLog = ExpenseOperationLog::where('expense_id', $item['id'])
                    ->order('create_time', 'desc')
                    ->find();
                $item['last_operation'] = $lastLog ? $lastLog->toArray() : null;
                $statusMap = [
                    0 => '待提交',
                    1 => '待审核',
                    2 => '已退回',
                    3 => '已通过'
                ];
                $item['status_desc'] = $statusMap[$item['current_status']] ?? '未知状态';
                // 添加申请人和费用类型名称
                $item['applicant_name'] = $item['applicant']['nickname'] ?? '';
                $item['expense_type_name'] = $item['expense_type']['name'] ?? '';
                // 移除关联数据
                unset($item['applicant'], $item['expense_type']);
            }
            return [
                'success' => true,
                'data' => [
                    'list' => $items,
                    'count' => $list['total'],
                    'page' => $list['current_page'],
                    'limit' => $list['per_page'],
                    'current_user' => [
                        'id' => $user->id,
                        'nickname' => $user->nickname
                    ]
                ]
            ];
        } catch (\Exception $e) {
            Log::error('Error in UserExpenseApplicationLogic::lists:' . $e->getMessage());
            return [
                'success' => false,
                'message' => $e->getMessage(),
            ];
        }
    }

    /**
     * 获取操作日志列表
     * @param int $expenseId
     * @param int $userId
     * @return array
     */
    public static function getOperationLogs(int $expenseId, int $userId): array
    {
        try {
            $user = User::find($userId);
            if (!$user || $user->is_locked) {
                throw new \Exception('账号状态异常，无法查看日志');
            }

            // 验证是否是本人的申请
            $application = ExpenseApplication::where([
                'id' => $expenseId,
                'applicant_men' => $user->nickname
            ])->findOrEmpty();
            
            if ($application->isEmpty()) {
                throw new \Exception('无权查看该申请的操作日志');
            }

            $logs = ExpenseOperationLog::where('expense_id', $expenseId)
                ->order('create_time', 'desc')
                ->select()
                ->toArray();

            return [
                'success' => true,
                'data' => $logs
            ];
        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => $e->getMessage()
            ];
        }
    }

    /**
     * @notes 获取费用类型列表（用于下拉选择）
     * @return array
     */
    public static function getExpenseTypes(): array
    {
        try {
            $expenseTypes = \app\common\model\reimbursement\ExpenseType::where('status', 0)  // 只获取启用状态的
                ->where('delete_time', null)  // 未删除的
                ->field(['id', 'name'])
                ->select()
                ->toArray();

            return [
                'success' => true,
                'data' => array_map(function($item) {
                    return [
                        'id' => $item['id'],
                        'name' => $item['name']
                    ];
                }, $expenseTypes)
            ];
        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => '获取费用类型列表失败'
            ];
        }
    }
}